#region license
/*
 * Copyright (C) 2007 CchenSoft.com
 * 
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License 2.1 or later, as
 * published by the Free Software Foundation. See the included License.txt
 * or http://www.gnu.org/copyleft/lesser.html for details.
 * 
 * Author: Billy Zhang
 */
#endregion

using System.Collections;
using System.Xml;
using System;
using System.Collections.Generic;

namespace CchenSoft.Workflow.Loader
{
    public class JoinDescriptor : AbstractDescriptor, IValidatable
    {
        //~ Instance fields ////////////////////////////////////////////////////////

        protected List<BaseConditionDescriptor> conditions = new List<BaseConditionDescriptor>();
        protected ResultDescriptor result;

        //~ Constructors ///////////////////////////////////////////////////////////

        /**
         * @deprecated use {@link DescriptorFactory} instead
         */
        public JoinDescriptor()
        {
        }

        /**
         * @deprecated use {@link DescriptorFactory} instead
         */
        public JoinDescriptor(XmlElement join)
        {
            Init(join);
        }

        //~ Methods ////////////////////////////////////////////////////////////////

        public IList<BaseConditionDescriptor> Conditions
        {
            get { return conditions; }
        }

        public ResultDescriptor Result
        {
            get { return result; }
            set { result = value; }
        }

        public void Validate()
        {
            ValidationHelper.Validate((ICollection<IValidatable>)conditions);

            if (result == null)
            {
                throw new InvalidWorkflowDescriptorException("Join has no result");
            }

            result.Validate();
        }

        public override void WriteXML(XmlTextWriter writer, int indent)
        {
            XMLUtil.printIndent(writer, indent++);
            writer.WriteStartElement("join");
            writer.WriteAttributeString("id", Id.ToString());

            if (conditions.Count > 0)
            {
                for (int i = 0; i < conditions.Count; i++)
                {
                    ConditionsDescriptor condition = (ConditionsDescriptor)conditions[i];
                    condition.WriteXML(writer, indent);
                }
            }

            if (result != null)
            {
                result.WriteXML(writer, indent);
            }

            XMLUtil.printIndent(writer, --indent);
            writer.WriteEndElement(); // ("</join>");
        }

        protected void Init(XmlElement join)
        {
            string id = XMLUtil.GetAttributeValue(join, "id");
            try
            {
                Id = (Convert.ToInt32(id));
            }
            catch (Exception ex)
            {
                throw new ArgumentException("Invalid join id value " + id);
            }

            // get conditions
            XmlNodeList conditionNodes = join.SelectNodes("conditions");
            int length = conditionNodes.Count;

            for (int i = 0; i < length; i++)
            {
                XmlElement condition = (XmlElement)conditionNodes[i];
                ConditionsDescriptor conditionDescriptor = DescriptorFactory.GetFactory().CreateConditionsDescriptor(condition);
                conditionDescriptor.Parent = this;
                this.conditions.Add(conditionDescriptor);
            }

            //<unconditional-result status="Underway" owner="test" step="2"/>
            XmlNode resultElement = join.SelectSingleNode("unconditional-result");

            // [KAP] This allows loading a workflow with Joins without unconditional-results
            if (resultElement != null)
            {
                result = new ResultDescriptor((XmlElement)resultElement);
                result.Parent = this;
            }
        }
    }
}
